"""
路由相关的数据模式定义
"""

from pydantic import BaseModel, Field, validator
from typing import List, Optional, Dict, Any
from datetime import datetime


class RouteBase(BaseModel):
    """路由基础模式"""
    path: str = Field(..., description="路由路径", max_length=255)
    name: str = Field(..., description="路由名称", max_length=100)
    display_name: str = Field(..., description="显示名称", max_length=100)
    description: Optional[str] = Field(None, description="路由描述")
    icon: Optional[str] = Field(None, description="图标名称", max_length=50)
    component: Optional[str] = Field(None, description="组件路径", max_length=255)
    parent_id: Optional[int] = Field(None, description="父路由ID")
    sort_order: int = Field(0, description="排序顺序")
    is_menu: bool = Field(True, description="是否显示在菜单中")
    is_active: bool = Field(True, description="是否启用")
    meta: Optional[Dict[str, Any]] = Field(None, description="路由元数据")

    @validator('path')
    def validate_path(cls, v):
        if not v.startswith('/'):
            raise ValueError('路由路径必须以 / 开头')
        return v

    @validator('name')
    def validate_name(cls, v):
        if not v.replace('_', '').replace('-', '').isalnum():
            raise ValueError('路由名称只能包含字母、数字、下划线和连字符')
        return v


class RouteCreate(RouteBase):
    """创建路由模式"""
    pass


class RouteUpdate(BaseModel):
    """更新路由模式"""
    name: Optional[str] = Field(None, description="路由名称", max_length=100)
    display_name: Optional[str] = Field(None, description="显示名称", max_length=100)
    description: Optional[str] = Field(None, description="路由描述")
    icon: Optional[str] = Field(None, description="图标名称", max_length=50)
    component: Optional[str] = Field(None, description="组件路径", max_length=255)
    parent_id: Optional[int] = Field(None, description="父路由ID")
    sort_order: Optional[int] = Field(None, description="排序顺序")
    is_menu: Optional[bool] = Field(None, description="是否显示在菜单中")
    is_active: Optional[bool] = Field(None, description="是否启用")
    meta: Optional[Dict[str, Any]] = Field(None, description="路由元数据")

    @validator('name')
    def validate_name(cls, v):
        if v is not None and not v.replace('_', '').replace('-', '').isalnum():
            raise ValueError('路由名称只能包含字母、数字、下划线和连字符')
        return v


class PermissionInfo(BaseModel):
    """权限信息模式"""
    id: int
    name: str
    display_name: str
    description: Optional[str]
    resource: str
    action: str

    class Config:
        from_attributes = True


class RoutePermissionResponse(BaseModel):
    """路由权限关联响应模式"""
    id: int
    route_id: int
    permission_id: int
    is_required: bool
    is_active: bool
    created_at: datetime
    permission: PermissionInfo

    class Config:
        from_attributes = True


class RouteResponse(BaseModel):
    """路由响应模式"""
    id: int
    path: str
    name: str
    display_name: str
    description: Optional[str]
    icon: Optional[str]
    component: Optional[str]
    parent_id: Optional[int]
    sort_order: int
    is_menu: bool
    is_active: bool
    is_system: bool
    meta: Optional[Dict[str, Any]]
    created_at: datetime
    updated_at: datetime
    
    # 关联数据
    children: Optional[List['RouteResponse']] = Field(None, description="子路由")
    permissions: Optional[List[PermissionInfo]] = Field(None, description="所需权限")
    permission_names: Optional[List[str]] = Field(None, description="权限名称列表")

    class Config:
        from_attributes = True

    @classmethod
    def from_orm(cls, obj):
        """从ORM对象创建响应模式"""
        data = {
            'id': obj.id,
            'path': obj.path,
            'name': obj.name,
            'display_name': obj.display_name,
            'description': obj.description,
            'icon': obj.icon,
            'component': obj.component,
            'parent_id': obj.parent_id,
            'sort_order': obj.sort_order,
            'is_menu': obj.is_menu,
            'is_active': obj.is_active,
            'is_system': obj.is_system,
            'meta': obj.meta,
            'created_at': obj.created_at,
            'updated_at': obj.updated_at,
        }
        
        # 处理子路由 - 避免懒加载
        try:
            # 检查children是否已经加载（避免懒加载）
            children_loaded = hasattr(obj, '__dict__') and 'children' in obj.__dict__
            if children_loaded and obj.children:
                data['children'] = [cls.from_orm(child) for child in obj.children]
        except Exception:
            # 如果访问children失败，跳过子路由
            pass

        # 处理权限信息 - 避免懒加载
        try:
            # 检查route_permissions是否已经加载
            permissions_loaded = hasattr(obj, '__dict__') and 'route_permissions' in obj.__dict__
            if permissions_loaded and obj.route_permissions:
                permissions = []
                permission_names = []
                for rp in obj.route_permissions:
                    if rp.is_active and rp.permission:
                        permissions.append(PermissionInfo.from_orm(rp.permission))
                        permission_names.append(rp.permission.name)
                data['permissions'] = permissions
                data['permission_names'] = permission_names
        except Exception:
            # 如果访问权限失败，跳过权限信息
            pass
        
        return cls(**data)


class RouteListResponse(BaseModel):
    """路由列表响应模式"""
    routes: List[RouteResponse]
    total: int

    class Config:
        from_attributes = True


class RoutePermissionAssign(BaseModel):
    """路由权限分配模式"""
    permission_ids: List[int] = Field(..., description="权限ID列表")

    @validator('permission_ids')
    def validate_permission_ids(cls, v):
        if not v:
            raise ValueError('权限ID列表不能为空')
        if len(v) != len(set(v)):
            raise ValueError('权限ID列表不能包含重复项')
        return v


class MenuRouteResponse(BaseModel):
    """菜单路由响应模式（简化版）"""
    id: int
    path: str
    name: str
    display_name: str
    icon: Optional[str]
    sort_order: int
    children: Optional[List['MenuRouteResponse']] = None

    class Config:
        from_attributes = True

    @classmethod
    def from_route(cls, route):
        """从Route对象创建菜单响应"""
        data = {
            'id': route.id,
            'path': route.path,
            'name': route.name,
            'display_name': route.display_name,
            'icon': route.icon,
            'sort_order': route.sort_order,
        }
        
        if hasattr(route, 'children') and route.children:
            # 只包含菜单项的子路由
            menu_children = [child for child in route.children if child.is_menu and child.is_active]
            if menu_children:
                # 按排序顺序排列
                menu_children.sort(key=lambda x: x.sort_order)
                data['children'] = [cls.from_route(child) for child in menu_children]
        
        return cls(**data)


# 更新前向引用
RouteResponse.model_rebuild()
MenuRouteResponse.model_rebuild()
